// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This file is part of CodingEditor.
// Note:	This project is derived from Peter Project
//			(hosted on sourceforge and codeplex)
//
// Copyright (c) 2008-2009, CE Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


namespace CE.Main
{
	using System;
	using System.IO;
	using System.Text;
	using System.Windows.Forms;
	using System.Xml;

	public sealed partial class CEProject : Form
	{
		#region Fields

		private string m_ProjectFile;

		#endregion Fields

		#region Constructors

		public CEProject()
		{
			InitializeComponent();
			/*m_ProjectFile = null*/;
			cmbType.SelectedIndex = 0;
			cmbExt.SelectedIndex = 0;
			btnOK.Enabled = false;
		}

		#endregion Constructors

		#region Properties

		/// <summary>
		/// Gets the location of the project...
		/// </summary>
		public string ProjectFile
		{
			get { return m_ProjectFile; }
		}

		#endregion Properties

		#region Methods

		public void SetProjectFile(string filePath)
		{
			try {
				m_ProjectFile = filePath;
				var xDoc = new XmlDocument();
				xDoc.Load(filePath);
				XmlNodeList nodes = xDoc.GetElementsByTagName("name");
				if (nodes.Count > 0) {
					txtProjectName.Text = nodes[0].InnerText;
				}

				nodes = xDoc.GetElementsByTagName("type");
				if (nodes.Count > 0) {
					cmbType.SelectedItem = nodes[0].InnerText;
				}

				nodes = xDoc.GetElementsByTagName("folder");
				foreach (XmlNode node in nodes) {
					lstFolders.Items.Add(node.InnerText);
				}

				nodes = xDoc.GetElementsByTagName("file");
				foreach (XmlNode node in nodes) {
					lstFiles.Items.Add(node.InnerText);
				}

				nodes = xDoc.GetElementsByTagName("WorkingDir");
				if (nodes.Count > 0) {
					txtWorkingDir.Text = nodes[0].InnerText;
				}

				nodes = xDoc.GetElementsByTagName("BuildScript");
				if (nodes.Count > 0) {
					richTextBox1.Text = nodes[0].InnerText;
				}

				nodes = xDoc.GetElementsByTagName("ExcludeFolderFilter");
				if (nodes.Count > 0) {
					txtExcludeFilterFolder.Text = nodes[0].InnerText;
				}

				nodes = xDoc.GetElementsByTagName("ExcludeFileFilter");
				if (nodes.Count > 0) {
					txtExcludeFilterFile.Text = nodes[0].InnerText;
				}

				nodes = xDoc.GetElementsByTagName("BuildFile");
				foreach (XmlNode node in nodes) {
					string file = "";
					bool check = false;

					foreach (XmlNode cNode in node.ChildNodes) {
						if (cNode.Name.ToLower() == "file") {
							file = cNode.InnerText;
						}
						if (cNode.Name.ToLower() == "prebuild") {
							check = Convert.ToBoolean(cNode.InnerText);
						}
					}

					clbBuildFiles.Items.Add(file, check);
				}
			}
			catch (Exception ex) {
				Console.WriteLine(ex.Message);
			}
		}

		private void Project_FormClosing(object sender, FormClosingEventArgs e)
		{
			Dispose(true);
		}

		private void WriteXml(string fileName)
		{
			var writer = new XmlTextWriter(fileName, Encoding.Unicode);
			try {
				writer.Indentation = 4;
				writer.Formatting = Formatting.Indented;
				writer.WriteComment("Created by Coding Editor");
				writer.WriteStartElement("CodingEditorProject");

				// Project Name...
				writer.WriteStartElement("name");
				writer.WriteValue(txtProjectName.Text);
				writer.WriteEndElement();

				// Project Type...
				writer.WriteStartElement("type");
				writer.WriteValue(cmbType.SelectedItem.ToString());
				writer.WriteEndElement();

				// Folders...
				for (int a = 0; a < lstFolders.Items.Count; a++) {
					writer.WriteStartElement("folder");
					writer.WriteValue(lstFolders.Items[a].ToString());
					writer.WriteEndElement();
				}

				// Files...
				for (int a = 0; a < lstFiles.Items.Count; a++) {
					writer.WriteStartElement("file");
					writer.WriteValue(lstFiles.Items[a].ToString());
					writer.WriteEndElement();
				}

				// Filter Settings...
				writer.WriteStartElement("ExcludeFolderFilter");
				writer.WriteValue(txtExcludeFilterFolder.Text);
				writer.WriteEndElement();
				writer.WriteStartElement("ExcludeFileFilter");
				writer.WriteValue(txtExcludeFilterFile.Text);
				writer.WriteEndElement();

				// Build Settings...
				writer.WriteStartElement("BuildSettings");
				// Working Directory...
				writer.WriteStartElement("WorkingDir");
				writer.WriteValue(txtWorkingDir.Text.Trim());
				writer.WriteEndElement();
				// Build Script..
				writer.WriteStartElement("BuildScript");
				writer.WriteValue(richTextBox1.Text);
				writer.WriteEndElement();
				// Build Files..
				for (int a = 0; a < clbBuildFiles.Items.Count; a++) {
					writer.WriteStartElement("BuildFile");
					writer.WriteStartElement("PreBuild");
					writer.WriteValue(clbBuildFiles.GetItemChecked(a).ToString());
					writer.WriteEndElement();
					writer.WriteStartElement("file");
					writer.WriteValue(clbBuildFiles.Items[a].ToString());
					writer.WriteEndElement();
					writer.WriteEndElement();
				}
				writer.WriteEndElement();
				writer.WriteEndElement();
			} finally {
				writer.Flush();
				writer.Close();
			}
		}

		private void btnAddBuildfile_Click(object sender, EventArgs e)
		{
			openFileDialog1.FileName = "";
			openFileDialog1.Filter = "";
			if (openFileDialog1.ShowDialog() == DialogResult.OK) {
				foreach (string file in openFileDialog1.FileNames) {
					clbBuildFiles.Items.Add(file);
				}
			}
		}

		private void btnAddFile_Click(object sender, EventArgs e)
		{
			if (openFileDialog1.ShowDialog() == DialogResult.OK) {
				foreach (string file in openFileDialog1.FileNames) {
					lstFiles.Items.Add(file);
				}
			}
		}

		private void btnAddFolder_Click(object sender, EventArgs e)
		{
			if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) {
				lstFolders.Items.Add(folderBrowserDialog1.SelectedPath);
			}
		}

		private void btnBrowseDir_Click(object sender, EventArgs e)
		{
			if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) {
				txtWorkingDir.Text = folderBrowserDialog1.SelectedPath;
			}
		}

		private void btnMoveBuildFileDown_Click(object sender, EventArgs e)
		{
			if (clbBuildFiles.SelectedIndex == clbBuildFiles.Items.Count - 1) {
				return;
			}

			int index = clbBuildFiles.SelectedIndex;
			object item = clbBuildFiles.Items[index];
			clbBuildFiles.Items.Remove(item);
			clbBuildFiles.Items.Insert(index + 1, item);
			clbBuildFiles.SelectedIndex = index + 1;
		}

		private void btnMoveBuildFileUp_Click(object sender, EventArgs e)
		{
			if (clbBuildFiles.SelectedIndex == 0) {
				return;
			}

			int index = clbBuildFiles.SelectedIndex;
			object item = clbBuildFiles.Items[index];
			clbBuildFiles.Items.Remove(item);
			clbBuildFiles.Items.Insert(index - 1, item);
			clbBuildFiles.SelectedIndex = index - 1;
		}

		private void btnOK_Click(object sender, EventArgs e)
		{
			if (string.IsNullOrEmpty(m_ProjectFile)) {
				saveFileDialog1.Filter = "Coding Editor Project (*.ceproj)|*.ceproj";
				saveFileDialog1.FileName = txtProjectName.Text;

				if (txtWorkingDir.Text.Length > 0)
					saveFileDialog1.InitialDirectory = txtWorkingDir.Text;

				if (saveFileDialog1.ShowDialog() == DialogResult.OK) {
					WriteXml(saveFileDialog1.FileName);
					m_ProjectFile = saveFileDialog1.FileName;
					Hide();
				}
			} else {
				if (File.Exists(m_ProjectFile)) {
					File.Delete(m_ProjectFile);
				}

				WriteXml(m_ProjectFile);
				Close();
			}
		}

		private void btnRemoveFile_Click(object sender, EventArgs e)
		{
			if (lstFiles.SelectedIndex >= 0) {
				lstFiles.Items.Remove(lstFiles.SelectedItem);
			}
		}

		private void btnRemoveFolder_Click(object sender, EventArgs e)
		{
			if (lstFolders.SelectedIndex >= 0) {
				lstFolders.Items.Remove(lstFolders.SelectedItem);
			}
		}

		private void cmbType_SelectedIndexChanged(object sender, EventArgs e)
		{
			switch (cmbType.SelectedIndex) {
			    case 0:
				    cmbExt.Items.Clear();
				    cmbExt.Items.AddRange(new object[] {".cpp", ".h"});
				    cmbExt.SelectedIndex = 0;
				    break;
			    case 1:
				    cmbExt.Items.Clear();
				    cmbExt.Items.AddRange(new object[] {".cs"});
				    cmbExt.SelectedIndex = 0;
				    break;
			}
		}

		private void mnucreateFile_Click(object sender, EventArgs e)
		{
			if (txtWorkingDir.Text != "") {
				var newFile = new CreateNewFile(txtWorkingDir.Text, cmbExt.SelectedIndex,
				                                cmbType.SelectedIndex);
				newFile.ShowDialog();
			} else
				MessageBox.Show("Specify a Working Directory first !", "CodingEditor",
				                MessageBoxButtons.OK, MessageBoxIcon.Stop);
		}

		private void txtProjectName_TextChanged(object sender, EventArgs e)
		{
			btnOK.Enabled =
			        (txtWorkingDir.TextLength > 0 && txtProjectName.TextLength > 0) ? true : false;
		}

		private void txtWorkingDir_TextChanged(object sender, EventArgs e)
		{
			btnOK.Enabled =
			        (txtWorkingDir.TextLength > 0 && txtProjectName.TextLength > 0) ? true : false;
		}

		#endregion Methods
	}
}